//
// Created by Deng on 2024/3/21.
//

#include "inc/net_op.h"

#include <string.h>

int op_socket(const char *protocol)
{
    int sockfd = -1;
    if (0 == strcmp(protocol, "tcp"))
    {
        sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // tcp socket
    }
    else if (0 == strcmp(protocol, "udp"))
    {
        sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); // udp socket
    }

    return sockfd;
}

int op_bind(int _sockfd, void *addr_var)
{
    return bind(_sockfd, (struct sockaddr *)addr_var, sizeof(struct sockaddr));
}

int op_listen(int _sockfd, int queue)
{
    return listen(_sockfd, queue);
}

int op_connect(int _sockfd, void *addr_var)
{

    return connect(_sockfd, (struct sockaddr *)addr_var, sizeof(struct sockaddr));
}

int create_netnode(struct NetNode *nn, int mode, const char *_ip, const int port)
{

    memset(nn, 0, sizeof(struct NetNode));

    int __type = 0;
    int __protocol = 0;
    switch (mode)
    {
    case 0:
        __type = SOCK_STREAM;
        // __protocol = IPPROTO_TCP;
        break;
    case 1:
        __type = SOCK_DGRAM;
        // __protocol = IPPROTO_UDP;
        break;
    default:
        break;
    }

    nn->fd = socket(AF_INET, __type, __protocol);
    if (nn->fd)
    {
        printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
        exit(1);
    }

    nn->addr.sin_family = AF_INET;
    nn->addr.sin_addr.s_addr = inet_addr(_ip);
    nn->addr.sin_port = htons(port);

    return nn->fd;
}

int bind_netnode(struct NetNode *nn)
{
    int nbind = bind(nn->fd, (struct sockaddr *)&(nn->addr), sizeof(struct sockaddr));
    if (nbind == -1)
    {
        nn->addr.sin_port = htons(0);
        bind_netnode(nn);
    }
    else
    {
        // getsockname(nn->fd, (struct sockaddr *)&(nn->addr), &addrlen);
        return nbind;
    }
    return 0;
}
